package com.patsnap.data.npd.dw.etl.utils;

import com.patsnap.data.common.apollo.ApolloHelper;
import com.patsnap.data.common.apollo.ApolloQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.cli.*;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class CommandUtils {

    public static Options defaultOptions() {
        Options options = new Options();
        options.addOption(OptionBuilder.withDescription("input path").withLongOpt("input").hasArg(true).isRequired(false).create());
        options.addOption(OptionBuilder.withDescription("output path").withLongOpt("output").hasArg(true).isRequired(false).create());
        options.addOption(OptionBuilder.withDescription("data type").withLongOpt("target").hasArg(true).isRequired(false).create());
        options.addOption(OptionBuilder.withDescription("customize param").withLongOpt("customize").hasArg(true).isRequired(false).create());
        options.addOption(OptionBuilder.withLongOpt(ApolloHelper.APOLLO_ADDRESS).hasArg(true).isRequired(false).create());
        options.addOption(OptionBuilder.withLongOpt(ApolloHelper.APOLLO_APP_ID).hasArg(true).isRequired(false).create());
        options.addOption(OptionBuilder.withLongOpt(ApolloHelper.APOLLO_APP_CLUSTER).hasArg(true).isRequired(false).create());
        options.addOption(OptionBuilder.withLongOpt(ApolloHelper.APOLLO_APP_PROFILE).hasArg(true).isRequired(false).create());
        return options;
    }

    public static CommandLine parseArgs(Options options, String[] args) {
        if (!options.hasOption("job_name")) {
            options.addOption(OptionBuilder.withDescription("spark job name").withLongOpt("job_name").hasArg(true).isRequired(false).create());
        }
        if (!options.hasOption("master")) {
            options.addOption(OptionBuilder.withDescription("spark master").withLongOpt("master").hasArg(true).isRequired(false).create());
        }
        HelpFormatter formatter = new HelpFormatter();
        try {
            CommandLine line = mergeApolloConfig(options, args);
            Iterator<Option> iterator = line.iterator();
            while (iterator.hasNext()) {
                Option opt = iterator.next();
                String argName = opt.getLongOpt();
                if (argName == null) {
                    argName = opt.getOpt();
                }
                String[] values = line.getOptionValues(argName);
                for (String value : values) {
                    log.info(argName + " : " + value);
                }
            }
            return line;
        } catch (ParseException e) {
            formatter.printHelp("input as:", options);
            log.error("input error",e);
            System.exit(0);
        }
        return null;
    }

    /**
     * 合并apollo和启动入参，apollo值覆盖启动入参
     *
     * @return 合并后的parameterTool
     */
    public static CommandLine mergeApolloConfig(Options options, String[] args) throws ParseException{
        CommandLineParser parser = new PosixParser();
        CommandLine cmd = parser.parse(options, args, true);
        // 判断是否读取apollo
        if (cmd.hasOption(ApolloHelper.APOLLO_APP_ID)) {
            String appId = cmd.getOptionValue(ApolloHelper.APOLLO_APP_ID);
            String apolloAddress = cmd.getOptionValue(ApolloHelper.APOLLO_ADDRESS);
            String apolloToken = cmd.getOptionValue(ApolloHelper.APOLLO_TOKEN);
            String team =  cmd.getOptionValue(ApolloHelper.APOLLO_TEAM);
            String cluster =  cmd.getOptionValue(ApolloHelper.APOLLO_APP_CLUSTER);
            String profile =  cmd.getOptionValue(ApolloHelper.APOLLO_APP_PROFILE);
            ApolloQuery apolloQuery = new ApolloQuery(appId, profile, cluster);
            apolloQuery.setToken(apolloToken);
            apolloQuery.setApolloAddress(apolloAddress);
            apolloQuery.setTeam(team);
            Map<String, Object> result = ApolloHelper.getConfigs(apolloQuery);
            for (Option option : cmd.getOptions()) {
                if(result.containsKey(option.getLongOpt())){
                    result.remove(option.getLongOpt());
                }
            }
            List<String> configs = Arrays.stream(args).collect(Collectors.toList());
            parser = new PosixParser();
            result.forEach((key, value) -> {
                if(StringUtils.isNotBlank(value.toString())){
                    options.addOption(OptionBuilder.withLongOpt(key).hasArg(true).isRequired(true).create());
                    configs.add("--" + key);
                    configs.add(value.toString());
                }
            });
            cmd = parser.parse(options, configs.toArray(new String[configs.size()]));
            return cmd;
        }
        return cmd;
    }
}
